﻿//Created by Action Script Viewer - http://www.buraks.com/asv
package net.wooga.pets.models {
    import flash.events.*;
    import flash.geom.*;
    import org.swiftsuspenders.*;
    import net.wooga.pets.events.*;
    import __AS3__.vec.*;
    import net.wooga.pets.models.world.vos.areas.*;
    import net.wooga.pets.interfaces.*;
    import net.wooga.pets.constants.*;
    import org.robotlegs.mvcs.*;

    public class RoomSlotsModel extends Actor {

        private const NUMBER_OF_SLOTS_TO_CREATE:int = 96;
        private const COLOUMNS_NUMBER:int = 6;

        private var _slotMatrix:Array;
        private var _slotModules2x2:Array;
        private var _slotModules4x4:Array;
        private var _topFloor:int;
        private var _numberOfOccupiedSlots:int;
        private var _availableRoomSlotsNumber:int;
        private var _tempAvailableRoomSlots:int;
        private var _injection:Injector;

        public static const ELEVATOR_BEFORE_COLOUMN:int = 4;

        public function initialize():void{
            var _local1:Slot;
            this._injection = new Injector();
            this._injection.mapValue(IEventDispatcher, eventDispatcher);
            var _local2:Number = 0;
            var _local3:Number = 0;
            var _local4 = 1;
            var _local5 = 1;
            this._numberOfOccupiedSlots = 0;
            this._topFloor = -1;
            this._slotMatrix = [];
            this._slotModules2x2 = [];
            var _local6:SlotModule2x2 = this.create2x2Module(0);
            this._slotModules2x2.push(_local6);
            var _local7:SlotModule2x2 = this.create2x2Module(1);
            this._slotModules2x2.push(_local7);
            this._slotModules4x4 = [];
            var _local8:SlotModule4x4 = this.create4x4Module(0);
            this._slotModules4x4.push(_local8);
            var _local9:int;
            while (_local9 < this.NUMBER_OF_SLOTS_TO_CREATE) {
                _local2 = (GameConstants.ROOM_WIDTH * (_local5 - 1));
                if (_local5 >= ELEVATOR_BEFORE_COLOUMN){
                    _local2 = (_local2 + GameConstants.ELEVATOR_WIDTH);
                };
                _local3 = (GameConstants.ROOM_HEIGHT * _local4);
                _local3 = (_local3 + GameConstants.BASEMENT_HEIGHT);
                _local1 = new Slot(_local2, -(_local3));
                _local1.slotMatrix = this._slotMatrix;
                _local1.floor = (_local4 - 1);
                _local1.column = _local5;
                _local1.id = _local9;
                this._slotMatrix[_local9] = _local1;
                this._injection.injectInto(_local1);
                if ((((_local1.column == Slot.COLUMN_2)) || ((_local1.column == Slot.COLUMN_3)))){
                    if (_local6.isFull()){
                        _local6 = this.create2x2Module(this._slotModules2x2.length);
                        this._slotModules2x2.push(_local6);
                        if (_local6.isFull()){
                            _local8.add2x2Module(_local6);
                        };
                    };
                    _local6.addSlot(_local1);
                    if (_local6.isFull()){
                        _local8.add2x2Module(_local6);
                    };
                };
                if ((((_local1.column == Slot.COLUMN_4)) || ((_local1.column == Slot.COLUMN_5)))){
                    if (_local7.isFull()){
                        _local7 = this.create2x2Module(this._slotModules2x2.length);
                        this._slotModules2x2.push(_local7);
                    };
                    _local7.addSlot(_local1);
                    if (_local7.isFull()){
                        _local8.add2x2Module(_local7);
                    };
                };
                if ((((((((_local1.column == Slot.COLUMN_2)) || ((_local1.column == Slot.COLUMN_3)))) || ((_local1.column == Slot.COLUMN_4)))) || ((_local1.column == Slot.COLUMN_5)))){
                    if (_local8.isFull()){
                        _local8 = this.create4x4Module(this._slotModules4x4.length);
                        this._slotModules4x4.push(_local8);
                    };
                    _local8.addSlot(_local1);
                };
                if ((_local5 % this.COLOUMNS_NUMBER) == 0){
                    _local4++;
                    _local5 = 0;
                };
                _local5++;
                _local9++;
            };
        }
        public function setOccupied(_arg1:int):void{
            var _local2:Slot = this.getSlotById(_arg1);
            _local2.setOccupied();
        }
        public function resetRoomSlotsModel():void{
            var _local1:Slot;
            for each (_local1 in this._slotMatrix) {
                _local1 = null;
                this._slotModules2x2 = null;
                this._slotModules4x4 = null;
            };
            this.initialize();
            dispatch(new BuildingEvent(BuildingEvent.SLOTS_RESET));
        }
        public function getNextFreeSlot():Slot{
            if (this.getNextFreeSlots().length > 0){
                return (this.getNextFreeSlots()[0]);
            };
            l("no slot is free");
            return (null);
        }
        public function getNextFreeSlots():Vector.<Slot>{
            var _local3:Slot;
            var _local4:Boolean;
            var _local1:Vector.<Slot> = new Vector.<Slot>();
            var _local2:int;
            while (_local2 < this._slotMatrix.length) {
                _local3 = this._slotMatrix[_local2];
                _local4 = _local3.isFree();
                _local4 = ((_local4) && (_local3.isSlotColumnInBuildingRange()));
                if ((((_local3.floor >= 1)) && (_local4))){
                    _local4 = ((_local4) && (_local3.hasBottomOccupiedNeighbor()));
                };
                if ((((_local3.column == Slot.COLUMN_2)) && (_local4))){
                    _local4 = ((_local4) && (_local3.hasRightOccupiedNeighbor()));
                } else {
                    if ((((_local3.column == Slot.COLUMN_5)) && (_local4))){
                        _local4 = ((_local4) && (_local3.hasLeftOccupiedNeighbor()));
                    };
                };
                _local4 = ((_local4) && (SlotModule(this.get2x2ModuleOfSlot(_local3)).isActive));
                if (_local4){
                    _local1.push(_local3);
                };
                _local2++;
            };
            return (_local1);
        }
        public function getSlotById(_arg1:int):Slot{
            return (this._slotMatrix[_arg1]);
        }
        public function setTopFloor(_arg1:int):void{
            if (_arg1 <= this._topFloor){
                return;
            };
            this._topFloor = _arg1;
            dispatch(new BuildingEvent(BuildingEvent.TOP_FLOOR_CHANGED));
        }
        public function get topFloor():int{
            return (this._topFloor);
        }
        public function get availableRoomSlotsNumber():int{
            return ((this._availableRoomSlotsNumber + this._tempAvailableRoomSlots));
        }
        public function set availableRoomSlotsNumber(_arg1:int):void{
            this._availableRoomSlotsNumber = _arg1;
        }
        public function get freeSlots():int{
            return ((this.availableRoomSlotsNumber - this.getNumberOfOccupiedSlots()));
        }
        public function isSlotAvailable():Boolean{
            return ((this.availableRoomSlotsNumber > this.getNumberOfOccupiedSlots()));
        }
        public function getOccupiedSlots():Array{
            var _local2:Slot;
            var _local1:Array = [];
            var _local3:int;
            while (_local3 < this._slotMatrix.length) {
                _local2 = this._slotMatrix[_local3];
                if (_local2.isOccupied()){
                    _local1.push(_local2);
                };
                _local3++;
            };
            return (_local1);
        }
        public function getNumberOfOccupiedSlots():int{
            return (this.getOccupiedSlots().length);
        }
        public function get slotModules4x4():Array{
            return (this._slotModules4x4);
        }
        public function get slotModules2x2():Array{
            return (this._slotModules2x2);
        }
        public function isSlotInActive4x4Module(_arg1:Slot):Boolean{
            var _local2:SlotModule;
            _local2 = this.get4x4ModuleOfSlot(_arg1);
            return (_local2.isActive);
        }
        public function get2x2ModuleOfSlot(_arg1:Slot):SlotModule2x2{
            var _local2:SlotModule2x2;
            var _local3:int;
            while (_local3 < this._slotModules2x2.length) {
                _local2 = this._slotModules2x2[_local3];
                if (_local2.containsSlot(_arg1)){
                    return (_local2);
                };
                _local3++;
            };
            l("e no 2x2 module for slot found");
            return (null);
        }
        public function get4x4ModuleOfSlot(_arg1:Slot):SlotModule4x4{
            var _local2:SlotModule4x4;
            var _local3:int;
            while (_local3 < this._slotModules4x4.length) {
                _local2 = this._slotModules4x4[_local3];
                if (_local2.containsSlot(_arg1)){
                    return (_local2);
                };
                _local3++;
            };
            l("e no 4x4 module for slot found");
            return (null);
        }
        public function activateNext4x4Module():void{
            var _local1:SlotModule;
            var _local2:int;
            while (_local2 < this._slotModules4x4.length) {
                _local1 = this._slotModules4x4[_local2];
                if (_local1.isActive){
                    _local1 = this._slotModules4x4[(_local2 + 1)];
                    _local1.isActive = true;
                    return;
                };
                _local2++;
            };
        }
        public function getRoute(_arg1:int, _arg2:int):Array{
            var _local5:Array;
            var _local6:Array;
            var _local7:Array;
            if (_arg1 == _arg2){
                return ([]);
            };
            var _local3:Slot = this.getSlotById(_arg1);
            var _local4:Slot = this.getSlotById(_arg2);
            if (_local3.floor == _local4.floor){
                return (this.findRoute(_local3, _local4));
            };
            _local5 = this.findRouteToElevator(_local3);
            _local6 = this.findRouteToElevator(_local4).reverse();
            _local6.push(_local4.id);
            _local7 = _local5.concat(_local6);
            return (_local7);
        }
        public function getElevatorPos(_arg1:int):Point{
            var _local2:Number = ((GameConstants.ROOM_WIDTH * (ELEVATOR_BEFORE_COLOUMN - 1)) + (GameConstants.ELEVATOR_WIDTH / 2));
            var _local3:Number = (((-1 * (_arg1 + 1)) * GameConstants.ROOM_HEIGHT) + GameConstants.BASEMENT_HEIGHT);
            return (new Point(_local2, _local3));
        }
        private function create2x2Module(_arg1:int):SlotModule2x2{
            var _local2:SlotModule2x2 = new SlotModule2x2(_arg1);
            _local2.modules = this._slotModules2x2;
            this._injection.injectInto(_local2);
            return (_local2);
        }
        private function create4x4Module(_arg1:int):SlotModule4x4{
            var _local2:SlotModule4x4 = new SlotModule4x4(_arg1);
            _local2.modules = this._slotModules4x4;
            this._injection.injectInto(_local2);
            return (_local2);
        }
        private function findRoute(_arg1:Slot, _arg2:Slot):Array{
            var _local3:Array = [];
            var _local4:Slot = _arg1;
            while (((_local4.hasRightOccupiedNeighbor()) || ((((_local4.column == Slot.COLUMN_5)) && ((_local4.floor == 0)))))) {
                _local4 = _local4.getRightNeighbor();
                _local3.push(_local4.id);
                if (_local4 == _arg2){
                    return (_local3);
                };
            };
            _local4 = _arg1;
            _local3 = [];
            while (((_local4.hasLeftOccupiedNeighbor()) || ((((_local4.column == Slot.COLUMN_2)) && ((_local4.floor == 0)))))) {
                _local4 = _local4.getLeftNeighbor();
                _local3.push(_local4.id);
                if (_local4 == _arg2){
                    return (_local3);
                };
            };
            return ([]);
        }
        private function findRouteToElevator(_arg1:Slot):Array{
            var _local2:Array = [];
            var _local3:Slot = _arg1;
            if (_arg1.column >= RoomSlotsModel.ELEVATOR_BEFORE_COLOUMN){
                while (_local3.hasLeftOccupiedNeighbor()) {
                    _local3 = _local3.getLeftNeighbor();
                    _local2.push(_local3.id);
                    if (_local3.column == RoomSlotsModel.ELEVATOR_BEFORE_COLOUMN){
                        return (_local2);
                    };
                };
            } else {
                while (_local3.hasRightOccupiedNeighbor()) {
                    _local3 = _local3.getRightNeighbor();
                    _local2.push(_local3.id);
                    if (_local3.column == (RoomSlotsModel.ELEVATOR_BEFORE_COLOUMN - 1)){
                        return (_local2);
                    };
                };
            };
            return ([]);
        }
        public function getNearestFreeRoom(_arg1:String, _arg2:String, _arg3:BuildingVO, _arg4:String):Array{
            var _local5:IRoom;
            var _local6:Array;
            var _local7:int;
            var _local10:IArea;
            var _local11:int;
            var _local12:Array;
            var _local13:Slot;
            var _local14:Slot;
            var _local15:int;
            var _local16:int;
            var _local8:IRoom = IRoom(_arg3.getRoom(_arg1));
            var _local9:int = _local8.slotId;
            for each (_local10 in _arg3.rooms) {
                _local5 = (_local10 as IRoom);
                if (_local5){
                    if (_local5.reservedBy == _arg4){
                        _local5.reservedBy = null;
                    };
                    if ((((((_local5.type == _arg2)) && (_local5.isFree))) && (!(_local5.reservedBy)))){
                        _local11 = IRoom(_arg3.getRoom(_local5.id)).slotId;
                        _local12 = this.getRoute(_local9, _local11);
                        _local13 = this.getSlotById(_local9);
                        _local14 = this.getSlotById(_local11);
                        _local15 = Math.abs((_local13.floor - _local14.floor));
                        _local16 = (_local12.length + _local15);
                        if (((!(_local6)) || ((_local7 > _local16)))){
                            _local6 = _local12;
                            _local7 = _local16;
                        };
                    };
                };
            };
            return (_local6);
        }
        public function get tempAvailableRoomSlots():int{
            return (this._tempAvailableRoomSlots);
        }
        public function set tempAvailableRoomSlots(_arg1:int):void{
            this._tempAvailableRoomSlots = _arg1;
        }

    }
}//package net.wooga.pets.models 
